package com.zh.template;


import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.zh.exception.GlobalException;
import com.zh.properties.PayProperties;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;

/**
 * 获取推送模板
 */
@Slf4j
public class PayTemplate {
    private PayProperties payProperties;
    public PayTemplate(PayProperties payProperties){
        this.payProperties = payProperties;
    }


    /**
     * 支付结果验证签名，解密
     *
     * @param wechatSignature :HTTP 头 Wechatpay-Signature。应答的微信支付签名。
     * @param wechatPaySerial :HTTP 头 Wechatpay-Serial。微信支付平台证书的序列号，验签必须使用序列号对应的微信支付平台证书。
     * @param wechatpayNonce  :HTTP 头 Wechatpay-Nonce。签名中的随机数。
     * @param wechatTimestamp :HTTP 头 Wechatpay-Timestamp。签名中的时间戳。
     * @param requestBody     : 请求体内容
     */
    public Transaction parserNotify(String wechatPaySerial,
                                    String wechatpayNonce,
                                    String wechatSignature,
                                    String wechatTimestamp,
                                    String requestBody) {
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPaySerial)
                .nonce(wechatpayNonce)
                .signature(wechatSignature)
                .timestamp(wechatTimestamp)
                .body(requestBody)
                .build();


        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser((NotificationConfig) getConfig());
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            return transaction;
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException("支付结果解析失败");
        }


    }
    /**
     * 关闭订单
     * @param outTradeNo 支付单号
     */
    public void closeOrder(String outTradeNo){// 构建service
        Config config = getConfig();
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        CloseOrderRequest closeRequest = new CloseOrderRequest();
        closeRequest.setMchid(payProperties.getMerchantId());
        closeRequest.setOutTradeNo(outTradeNo);
// 方法没有返回值，意味着成功时API返回204 No Content
        service.closeOrder(closeRequest);
    }

    /**
     * 创建微信支付服务
     * @param openid  微信用户 openId
     * @param subject  商品描述 (备注)
     * @param money    订单金额
     * @param payOrderNo  支付单号
     * @return
     */
    public PrepayWithRequestPaymentResponse  createWechatPay(String openid, String subject, BigDecimal money,String payOrderNo) {
        Config config = getConfig();
        // 构建service
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        // request.setXxx(val)设置所需参数，具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();

        // 指定是否分账
        SettleInfo settleInfo = new SettleInfo();
        // 开启分账
        settleInfo.setProfitSharing(true);
        request.setSettleInfo(settleInfo);
        //  总金额】 订单总金额，单位为分。
        Amount amount = new Amount();
//        amount.setTotal(money);
        amount.setTotal(1);
        request.setAmount(amount);
        request.setAppid(payProperties.getAppId());
        request.setMchid(payProperties.getMerchantId());
        request.setDescription(subject);
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * 【通知地址】 异步接收微信支付结果通知的回调地址，通知URL必须为外网可访问的URL，
         * 不能携带参数。 公网域名必须为HTTPS，如果是走专线接入，使用专线NAT IP或者私有回调域名可使用HTTP
         * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        request.setNotifyUrl("http://caqr6r.natappfree.cc/drive/pay/app/pay/notify");
        request.setOutTradeNo(payOrderNo);
        Payer payer = new Payer();
        // 【用户标识】 用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID，详见OpenID获取
        payer.setOpenid(openid);
        request.setPayer(payer);
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        // 使用微信扫描 code_url 对应的二维码，即可体验Native支付
        System.out.println(response);
        return response;
    }

    /**
     * 初始化配置
     * @return
     */
    private  Config getConfig() {
        // 使用自动更新平台证书的RSA配置
        // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(payProperties.getMerchantId())
                        .privateKeyFromPath(payProperties.getPrivateKeyPath())
                        .merchantSerialNumber(payProperties.getMerchantSerialNumber())
                        .apiV3Key(payProperties.getApiV3Key())
                        .build();
        return config;
    }


}
